﻿using System;
using System.Collections.Generic;
using UniFrame.Scene;
using UnityEngine;

namespace UniFrame.UI
{
    /// <summary>
    /// UI面板基类
    /// </summary>
    public abstract class BasePanel
    {
        /// <summary>
        /// 面板基类
        /// </summary>
        /// <param name="path"></param>
        public BasePanel(string path)
        {
            uniRes = new UniRes(path);
            IsFirstLoad = true;
        }
        /// <summary>
        /// 面板基类
        /// </summary>
        /// <param name="uI"></param>
        public BasePanel(UniRes uI)
        {
            uniRes = uI ?? throw new NullReferenceException();    
            IsFirstLoad = true;
        }
        /// <summary>
        /// 当前场景
        /// </summary>
        public BaseScene baseScene { get {return uIManager.baseScene; } }
        /// <summary>
        /// 面板管理器
        /// </summary>
        public UIManager uIManager { get; private set; }
        /// <summary>
        /// 面板信息
        /// </summary>
        public UniRes uniRes { get; private set; }
        /// <summary>
        /// 面板游戏物体
        /// </summary>
        public GameObject gameObject { get; private set; }
        /// <summary>
        /// 面板游戏变换组件
        /// </summary>
        public Transform transform { get; private set; }
        /// <summary>
        /// 是否第一次加载
        /// </summary>
        internal bool IsFirstLoad { get; set; }
        /// <summary>
        /// 附加游戏对象
        /// </summary>
        internal void AttachGameObject(UIManager uIManager)
        {
            this.uIManager = uIManager;
            gameObject = uIManager.GetSingleUI(uniRes, this).gameObject;
            transform = gameObject.transform;
            gameObject.SetActive(false);
        }
        /// <summary>
        /// 初始化
        /// </summary>
        public virtual void Initialize()
        {

        }     
        /// <summary>
        /// 每次面板进入时调用
        /// </summary>
        public virtual void OnEnter()
        {            
            SetActive(true);
        }
        /// <summary>
        /// 每次面板暂停时调用
        /// </summary>
        public virtual void OnPause()
        {
            SetActive(false);
        }
        /// <summary>
        /// 每次面板恢复时调用
        /// </summary>
        public virtual void OnResume()
        {
            SetActive(true);
        }
        /// <summary>
        /// 每次面板退出时调用
        /// </summary>
        public virtual void OnExit()
        {
            SetActive(false);
        }
        /// <summary>
        /// 设置面板活动状态
        /// </summary>
        /// <param name="value"></param>
        public virtual void SetActive(bool value)
        {
            gameObject.SetActive(value);
        }
        /// <summary>
        /// 推入一个面板
        /// </summary>
        /// <param name="basePanel"></param>
        public void Push(BasePanel basePanel)
        {
            uIManager.Push(basePanel);
        }
        /// <summary>
        /// 弹出一个面板
        /// </summary>
        public void Pop()
        {
            uIManager.Pop();
        }
        /// <summary>
        /// 查找一个游戏对象
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public GameObject Find(string name)
        {
            Transform[] transforms = gameObject.GetComponentsInChildren<Transform>();
            foreach (Transform item in transforms)
                if (item.name == name)
                    return item.gameObject;
            return null;
        }
        /// <summary>
        /// 查找相同名字的对象
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public GameObject[] Finds(string name)
        {
            List<GameObject> gos = new List<GameObject>();
            Transform[] transforms = gameObject.GetComponentsInChildren<Transform>();
            foreach (Transform item in transforms)
            {
                if (item.name == name)
                    gos.Add(item.gameObject);
            }
            return gos.ToArray();

        }
        /// <summary>
        /// 查找含有指定标签的所有游戏对象
        /// </summary>
        /// <param name="tag"></param>
        /// <returns></returns>
        public GameObject[] FindGameObjectsWithTag(string tag)
        {
            List<GameObject> objects = new List<GameObject>();
            Transform[] transforms = gameObject.GetComponentsInChildren<Transform>();
            foreach (Transform item in transforms)
                if (item.CompareTag(tag))
                    objects.Add(item.gameObject);
            return objects.ToArray();
        }
        /// <summary>
        /// 获取一个游戏组件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetComponent<T>() where T : Component
        {
            return gameObject.GetComponent<T>();
        }
        /// <summary>
        /// 获取所有组件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T[] GetComponents<T>() where T :Component
        {
            List<T> ts = new List<T>();
            Transform[] transforms = gameObject.GetComponentsInChildren<Transform>();
            foreach (Transform item in transforms)
            {
                T component = item.GetComponent<T>();
                if (component != null)
                    ts.Add(component);
            }
            return ts.ToArray();
        }
        /// <summary>
        /// 获取某个游戏对象上的组件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        public T GetComponent<T>(string name) where T : Component
        {
            return Find(name).GetComponent<T>();
        }
        /// <summary>
        /// 添加一个组件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T AddComponent<T>() where T : Component
        {
            return gameObject.AddComponent<T>();
        }
        /// <summary>
        /// 给某个游戏对象添加一个组件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        public T AddComponent<T>(string name) where T : Component
        {
            GameObject go = Find(name);
            if (go == null)
                return null;
            return Find(name).AddComponent<T>();
        }
        /// <summary>
        /// 获取或添加一个组件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetOrAddComponent<T>() where T : Component
        {
            T component = GetComponent<T>();
            if (component == null)
                component = AddComponent<T>();
            return component;
        }
        /// <summary>
        /// 获取或添加某一个游戏对象的组件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        public T GetOrAddComponent<T>(string name) where T : Component
        {
            GameObject go = Find(name);
            if (go == null)
                return null;
            T component = go.GetComponent<T>();
            if (component == null)
                go.AddComponent<T>();
            return component;
        }
        /// <summary>
        /// 设置某个CanvasGroup状态
        /// </summary>
        /// <param name="group"></param>
        /// <param name="flag"></param>
        public void SetCanvasGroup(CanvasGroup group, bool flag)
        {
            if (flag)
            {
                group.alpha = 1.0f;
                group.interactable = true;
                group.blocksRaycasts = true;
            }
            else
            {
                group.alpha = 0.0f;
                group.interactable = false;
                group.blocksRaycasts = false;
            }

        }
        /// <summary>
        /// 比较两个面板的资源类型
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            BasePanel target = obj as BasePanel;
            return uniRes.Equals(target.uniRes);
        }
        /// <summary>
        /// 返回资源类型哈希值
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return uniRes.GetHashCode();
        }       
    }

}
